package com.edvard.backup;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.edvard.jsbackup.R;
import com.edvard.util.DatabaseHelper;
import com.edvard.util.GetPostUtil;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.utils.UrlSafeBase64;

import org.json.JSONObject;

import java.io.File;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


/**
 * Created by HackerZ
 */
public class QiNiuBackupActivity extends Activity implements View.OnClickListener{


    private static final String TAG = "BackupActivity";
    private static final String DATABASE_NAME = "financial.db";

    /**
     * 七牛云存储的 AccessKey 和 SecretKey
     * zhijie
     */
    private static final String APP_KEY = "自己的AccessKey";
    private static final String APP_SECRET = "自己的SecretKey";



    /**
     * 控件变量
     */
    Button btnBack;
    TextView tvBackup, tvRecover;
    LinearLayout llSync;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qiniu_backup);

        findViewById();
        setListener();
        // 获取上传 Token
        getToken();
    }

    public void findViewById() {
        btnBack = (Button) findViewById(R.id.btn_backup_back);
        tvBackup = (TextView) findViewById(R.id.tv_backup);
        tvRecover = (TextView) findViewById(R.id.tv_recover);
        llSync = (LinearLayout) findViewById(R.id.ll_sync);
    }
    public void setListener() {
        btnBack.setOnClickListener(this);
        tvBackup.setOnClickListener(this);
        tvRecover.setOnClickListener(this);
    }

    /**
     * 点击事件
     */
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

        if (v == btnBack)
            QiNiuBackupActivity.this.finish();

        if (v == tvBackup) {
            /**
             * 上传数据库文件 调用了UploadDBFile进行备份
             */
            showAlertDialog("确定备份", "确定", "取消",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            /**
                             * 上传数据库文件
                             */
                            uploadDBFile();
                        }
                    }, null);
        }

        /**
         * 判断数据库文件是否存在 删除当前数据库 将数据库放在指定文件夹内
         */
        if (v == tvRecover) {
            /**
             * 检查云端是否存在备份过的数据库文件
             */
            showAlertDialog("确定还原", "确定", "取消",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            final Handler h = new Handler(){
                            @Override
                            public void handleMessage(Message msg) {
                                if(msg.what==0x123){
                                    Toast.makeText(getApplicationContext(),"恢复备份完成",Toast.LENGTH_SHORT).show();
                                }
                            }
                        };
                            new Thread(new AccessNetwork("GET", "http://7xltko.com1.z0.glb.clouddn.com/"+ DATABASE_NAME, null, h)).start();
                        }
                    }, null);
        }
    }




    class AccessNetwork implements Runnable{
        private String op ;
        private String url;
        private String params;
        private Handler h;

        public AccessNetwork(String op, String url, String params,Handler h) {
            super();
            this.op = op;
            this.url = url;
            this.params = params;
            this.h = h;
        }

        @Override
        public void run() {
            Message m = new Message();
            m.what = 0x123;
            if(op.equals("GET")){
                Log.i("iiiiiii","发送GET请求");
                m.obj = GetPostUtil.downFile(url, "/data/data/com.edvard.jsbackup/databases/", DATABASE_NAME);
                Log.i("iiiiiii",">>>>>>>>>>>>"+m.obj);
            }
            if(op.equals("POST")){
                Log.i("iiiiiii","发送POST请求");
                m.obj = GetPostUtil.sendPost(url, params);
                Log.i("gggggggg",">>>>>>>>>>>>"+m.obj);
            }
            h.sendMessage(m);
        }
    }

    /**
     *
     * @param title
     *            标题
     * @param strPositive
     *            确定按钮显示的字符串
     * @param strNegetive
     *            取消按钮显示的字符串
     * @param posit
     *            确定按钮的点击事件
     * @param neget
     *            取消按钮的点击事件
     */
    public void showAlertDialog(String title, String strPositive,
                                String strNegetive, DialogInterface.OnClickListener posit,
                                DialogInterface.OnClickListener neget) {
        AlertDialog.Builder b = new AlertDialog.Builder(this);
        b.setTitle(title);
        b.setPositiveButton(strPositive, posit);
        b.setNegativeButton(strNegetive, neget);
        b.create().show();
    }


    /**
     * 上传数据库文件
     */
    public void uploadDBFile() {
        //得到数据库文件路径
        File dbFile = QiNiuBackupActivity.this
                .getDatabasePath(DatabaseHelper.DATABASE_NAME);
        // 重用 uploadManager。一般地，只需要创建一个 uploadManager 对象
        UploadManager uploadManager = new UploadManager();
        String token = getToken();
        uploadManager.put(dbFile, DATABASE_NAME, token,
                new UpCompletionHandler() {
                    @Override
                    public void complete(String key, ResponseInfo info, JSONObject res) {
                        //  res 包含hash、key等信息，具体字段取决于上传策略的设置。
                        Log.i("qiniu", key + ",\r\n " + info + ",\r\n " + res);
                        Toast.makeText(getApplicationContext(),"云备份完成！",Toast.LENGTH_LONG).show();
                    }
                }, null);
    }



    /**
     *
     * 本地生成 Token
     * 这种方法非常不安全，七牛中推荐的方法是由服务器生成 Token
     * */
    private String getToken () {
        String uploadToken = new String();
        try {
            JSONObject putPolicy = new JSONObject();
            putPolicy.put("scope","android-finaman-cloud-backup-hackerz:" + DATABASE_NAME);
            putPolicy.put("deadline",1451491200);

            // 将 JSONObject 转化为 String 然后进行 Base64 编码
            String encodedPutPolicy = UrlSafeBase64.encodeToString(putPolicy
                    .toString().getBytes());

            Log.i("encodedPutPolicy" ,encodedPutPolicy);

            byte[] sign = HmacSHA1Encrypt(encodedPutPolicy, APP_SECRET);
            String encodedSign = UrlSafeBase64.encodeToString(sign);

            // 最终完成拼接 上传文件的 Token
            uploadToken = APP_KEY + ':' + encodedSign + ':'
                    + encodedPutPolicy;
            Log.i("uploadToken:" ,uploadToken);
        }catch(Exception e){
            e.printStackTrace();
        }
        // 返回拼接完成的 uploadToken
        return uploadToken;
    }

    private static final String MAC_NAME = "HmacSHA1";
    private static final String ENCODING = "UTF-8";

    /**
     * 上传凭证组成
     *
     * 使用 HMAC-SHA1 签名方法对对encryptText进行签名
     * */
    public static byte[] HmacSHA1Encrypt(String encryptText, String encryptKey)
            throws Exception {
        byte[] data = encryptKey.getBytes(ENCODING);
        // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
        // 生成一个指定 Mac 算法 的 Mac 对象
        Mac mac = Mac.getInstance(MAC_NAME);
        // 用给定密钥初始化 Mac 对象
        mac.init(secretKey);
        byte[] text = encryptText.getBytes(ENCODING);
        // 完成 Mac 操作
        return mac.doFinal(text);
    }


}
